<template>
    <div class="gradient-bg" :style="cssVariables">
        <!-- 噪声背景 SVG -->
        <svg viewBox="0 0 100vw 100vw" xmlns="http://www.w3.org/2000/svg" class="noiseBg">
            <filter id="noiseFilterBg">
                <feTurbulence type="fractalNoise" baseFrequency="0.6" stitchTiles="stitch" />
            </filter>
            <rect width="100%" height="100%" preserveAspectRatio="xMidYMid meet" filter="url(#noiseFilterBg)" />
        </svg>

        <!-- 模糊滤镜 SVG -->
        <svg xmlns="http://www.w3.org/2000/svg" class="svgBlur">
            <defs>
                <filter id="goo">
                    <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
                    <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -8"
                        result="goo" />
                    <feBlend in="SourceGraphic" in2="goo" />
                </filter>
            </defs>
        </svg>

        <!-- 渐变容器 -->
        <div class="gradients-container">
            <div class="g1"></div>
            <div class="g2"></div>
            <div class="g3"></div>
            <div class="g4"></div>
            <div class="g5"></div>
            <div ref="interactiveRef" class="interactive" :style="interactiveStyle"></div>
        </div>

        <!-- 内容插槽 -->
        <div class="content-overlay">
            <slot></slot>
        </div>
    </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'

// Props 定义
const props = defineProps({
    // 自定义颜色配置
    colors: {
        type: Object,
        default: () => ({
            bg1: 'rgb(8, 10, 15)',
            bg2: 'rgb(0, 17, 32)',
            color1: '18, 113, 255',
            color2: '107, 74, 255',
            color3: '100, 100, 255',
            color4: '50, 160, 220',
            color5: '80, 47, 122',
            interactive: '140, 100, 255'
        })
    },
    // 圆形大小
    circleSize: {
        type: String,
        default: '80%'
    },
    // 混合模式
    blendMode: {
        type: String,
        default: 'hard-light'
    },
    // 是否启用鼠标交互
    enableInteractive: {
        type: Boolean,
        default: true
    },
    // 模糊强度
    blurIntensity: {
        type: Number,
        default: 40
    }
})

// 响应式状态
const interactiveRef = ref(null)
const curX = ref(0)
const curY = ref(0)
const tgX = ref(0)
const tgY = ref(0)
const animationId = ref(null)

// 计算样式
const interactiveStyle = computed(() => ({
    transform: `translate(${Math.round(curX.value)}px, ${Math.round(curY.value)}px)`
}))

// CSS 变量计算
const cssVariables = computed(() => ({
    '--color-bg1': props.colors.bg1,
    '--color-bg2': props.colors.bg2,
    '--color1': props.colors.color1,
    '--color2': props.colors.color2,
    '--color3': props.colors.color3,
    '--color4': props.colors.color4,
    '--color5': props.colors.color5,
    '--color-interactive': props.colors.interactive,
    '--circle-size': props.circleSize,
    '--blending': props.blendMode,
    '--blur-intensity': `${props.blurIntensity}px`
}))

// 动画函数
const moveAnimation = () => {
    curX.value += (tgX.value - curX.value) / 20
    curY.value += (tgY.value - curY.value) / 20
    animationId.value = requestAnimationFrame(moveAnimation)
}

// 鼠标移动处理
const handleMouseMove = (event) => {
    if (!props.enableInteractive) return
    tgX.value = event.clientX
    tgY.value = event.clientY
}

// 生命周期钩子
onMounted(() => {
    if (props.enableInteractive) {
        window.addEventListener('mousemove', handleMouseMove)
        moveAnimation()
    }
})

onUnmounted(() => {
    if (props.enableInteractive) {
        window.removeEventListener('mousemove', handleMouseMove)
        if (animationId.value) {
            cancelAnimationFrame(animationId.value)
        }
    }
})

// 暴露方法给父组件
defineExpose({
    // 更新目标位置（可用于编程式控制）
    updateTarget: (x, y) => {
        tgX.value = x
        tgY.value = y
    },
    // 重置位置
    resetPosition: () => {
        curX.value = 0
        curY.value = 0
        tgX.value = 0
        tgY.value = 0
    }
})
</script>

<style>
@import url("https://fonts.googleapis.com/css?family=Montserrat:400,700");

/* 重置样式 */
.gradient-bg * {
    margin: 0;
    padding: 0;
    outline: none;
    list-style: none;
    text-decoration: none;
    box-sizing: border-box;
}

/* 动画关键帧 */
@keyframes moveInCircle {
    0% {
        transform: rotate(0deg);
    }

    50% {
        transform: rotate(180deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

@keyframes moveVertical {
    0% {
        transform: translateY(-50%);
    }

    50% {
        transform: translateY(50%);
    }

    100% {
        transform: translateY(-50%);
    }
}

@keyframes moveHorizontal {
    0% {
        transform: translateX(-50%) translateY(-10%);
    }

    50% {
        transform: translateX(50%) translateY(10%);
    }

    100% {
        transform: translateX(-50%) translateY(-10%);
    }
}

/* 主容器 */
.gradient-bg {
    width: 100vw;
    height: 100vh;
    position: relative;
    overflow: hidden;
    background: linear-gradient(40deg, var(--color-bg1), var(--color-bg2));
    top: 0;
    left: 0;
}

.gradient-bg .svgBlur {
    display: none;
}

.gradient-bg .noiseBg {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    z-index: 1;
    mix-blend-mode: soft-light;
    opacity: 0.6;
}

.gradient-bg .gradients-container {
    filter: url(#goo) blur(var(--blur-intensity));
    width: 100%;
    height: 100%;
}

/* 渐变球样式 */
.gradient-bg .g1 {
    position: absolute;
    background: radial-gradient(circle at center,
            rgba(var(--color1), 0.8) 0,
            rgba(var(--color1), 0) 50%) no-repeat;
    mix-blend-mode: var(--blending);
    width: var(--circle-size);
    height: var(--circle-size);
    top: calc(50% - var(--circle-size) / 2);
    left: calc(50% - var(--circle-size) / 2);
    transform-origin: center center;
    animation: moveVertical 30s ease infinite;
    opacity: 1;
}

.gradient-bg .g2 {
    position: absolute;
    background: radial-gradient(circle at center,
            rgba(var(--color2), 0.8) 0,
            rgba(var(--color2), 0) 50%) no-repeat;
    mix-blend-mode: var(--blending);
    width: var(--circle-size);
    height: var(--circle-size);
    top: calc(50% - var(--circle-size) / 2);
    left: calc(50% - var(--circle-size) / 2);
    transform-origin: calc(50% - 400px);
    animation: moveInCircle 20s reverse infinite;
    opacity: 1;
}

.gradient-bg .g3 {
    position: absolute;
    background: radial-gradient(circle at center,
            rgba(var(--color3), 0.8) 0,
            rgba(var(--color3), 0) 50%) no-repeat;
    mix-blend-mode: var(--blending);
    width: var(--circle-size);
    height: var(--circle-size);
    top: calc(50% - var(--circle-size) / 2 + 200px);
    left: calc(50% - var(--circle-size) / 2 - 500px);
    transform-origin: calc(50% + 400px);
    animation: moveInCircle 40s linear infinite;
    opacity: 1;
}

.gradient-bg .g4 {
    position: absolute;
    background: radial-gradient(circle at center,
            rgba(var(--color4), 0.8) 0,
            rgba(var(--color4), 0) 50%) no-repeat;
    mix-blend-mode: var(--blending);
    width: var(--circle-size);
    height: var(--circle-size);
    top: calc(50% - var(--circle-size) / 2);
    left: calc(50% - var(--circle-size) / 2);
    transform-origin: calc(50% - 200px);
    animation: moveHorizontal 40s ease infinite;
    opacity: 0.7;
}

.gradient-bg .g5 {
    position: absolute;
    background: radial-gradient(circle at center,
            rgba(var(--color5), 0.8) 0,
            rgba(var(--color5), 0) 50%) no-repeat;
    mix-blend-mode: var(--blending);
    width: calc(var(--circle-size) * 2);
    height: calc(var(--circle-size) * 2);
    top: calc(50% - var(--circle-size));
    left: calc(50% - var(--circle-size));
    transform-origin: calc(50% - 800px) calc(50% + 200px);
    animation: moveInCircle 20s ease infinite;
    opacity: 1;
}

.gradient-bg .interactive {
    position: absolute;
    background: radial-gradient(circle at center,
            rgba(var(--color-interactive), 0.8) 0,
            rgba(var(--color-interactive), 0) 50%) no-repeat;
    mix-blend-mode: var(--blending);
    width: 100%;
    height: 100%;
    top: -50%;
    left: -50%;
    opacity: 0.7;
    transition: transform 0.1s ease-out;
}

/* 内容覆盖层 */
.gradient-bg .content-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* 响应式设计 */
@media (max-width: 768px) {
    .gradient-bg {
        --circle-size: 60%;
        --blur-intensity: 30px;
    }
}

@media (max-width: 480px) {
    .gradient-bg {
        --circle-size: 50%;
        --blur-intensity: 20px;
    }
}
</style>